package cn.wolfcode.car.business.service.impl;

import cn.wolfcode.car.business.domain.Appointment;
import cn.wolfcode.car.business.domain.Statement;
import cn.wolfcode.car.business.mapper.AppointmentMapper;
import cn.wolfcode.car.business.mapper.StatementMapper;
import cn.wolfcode.car.business.query.AppointmentQuery;
import cn.wolfcode.car.business.service.IAppointmentService;
import cn.wolfcode.car.common.base.page.TablePageInfo;
import cn.wolfcode.car.common.exception.BusinessException;
import cn.wolfcode.car.common.util.Convert;
import cn.wolfcode.car.common.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
@Transactional
public class AppointmentServiceImpl extends ServiceImpl<AppointmentMapper, Appointment> implements IAppointmentService {

    @Autowired
    private AppointmentMapper appointmentMapper;
    @Autowired
    private StatementMapper statementMapper;

    @Override
    public TablePageInfo<Appointment> query(AppointmentQuery qo) {
        // 分页信息
        IPage<Appointment> page = new Page<>(qo.getPageNum(), qo.getPageSize());

        // 过滤信息
        LambdaQueryWrapper<Appointment> wrapper = Wrappers.<Appointment>lambdaQuery();
        String customerName = qo.getCustomerName();
        String customerPhone = qo.getCustomerPhone();
        Integer status = qo.getStatus();
        wrapper.like(StringUtils.isNotEmpty(customerName), Appointment::getCustomerName, customerName)  // 姓名
                .like(StringUtils.isNotEmpty(customerPhone),Appointment::getCustomerPhone, customerPhone)   // 手机号
                .eq(StringUtils.isNotNull(status), Appointment::getStatus, status)  // 预约状态
                .eq(Appointment::getDeleteFlag, Appointment.DELETE_NO);

        TablePageInfo<Appointment> info = new TablePageInfo<>(super.page(page, wrapper).getRecords());
        info.setTotal(super.count());   // 设置总记录数
        return info;
    }

    @Override
    public void update(Appointment appointment) {
        // 根据id查询预约记录
        checkUpdate(appointment.getId());
        LambdaUpdateWrapper<Appointment> wrapper = Wrappers.<Appointment>lambdaUpdate();
        wrapper.eq(Appointment::getId, appointment.getId())
                .set(Appointment::getCustomerName, appointment.getCustomerName())
                .set(Appointment::getCustomerPhone, appointment.getCustomerPhone())
                .set(Appointment::getAppointmentTime, appointment.getAppointmentTime())
                .set(Appointment::getLicensePlate, appointment.getLicensePlate())
                .set(Appointment::getCarSeries, appointment.getCarSeries())
                .set(Appointment::getServiceType, appointment.getServiceType())
                .set(Appointment::getInfo, appointment.getInfo());
        appointmentMapper.update(null, wrapper);
    }

    @Override
    public void deleteBatch(String ids) {
        // 将字符串转为Long数组
        Long[] dictIds = Convert.toLongArray(ids);
        for (Long dictId : dictIds) {
            checkUpdate(dictId);
            LambdaUpdateWrapper<Appointment> wrapper = Wrappers.lambdaUpdate();
            wrapper.eq(Appointment::getId, dictId);
            wrapper.set(Appointment::getDeleteFlag, Appointment.DELETE_YES); // 软删除，将delete_flag改为已删除
            appointmentMapper.update(null, wrapper);
        }
    }

    @Override
    public void arrival(Long id) {
        checkUpdate(id);    // 检查操作是否合法
        LambdaUpdateWrapper<Appointment> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(Appointment::getId, id)
                .set(Appointment::getStatus, Appointment.STATUS_ARRIVAL)   // 修改状态为已到店
                .set(Appointment::getActualArrivalTime, new Date());     // 修改到店时间
        appointmentMapper.update(null, wrapper);
    }

    @Override
    public void cancel(Long id) {
        checkUpdate(id);    // 检查操作是否合法
        LambdaUpdateWrapper<Appointment> wrapper = Wrappers.lambdaUpdate();
        wrapper.set(Appointment::getStatus, Appointment.STATUS_CANCEL)   // 修改状态为取消
                .eq(Appointment::getId, id);
        this.update();
        appointmentMapper.update(null, wrapper);
    }

    // 检查修改是否合法
    private void checkUpdate(Long id) {
        Appointment appointment = appointmentMapper.selectById(id);
        // 预约记录状态不是预约中，抛出异常
        if (!Appointment.STATUS_APPOINTMENT.equals(appointment.getStatus())) {
            throw new BusinessException("该条预约记录不允许修改！");
        }
    }

    @Override
    @Transactional
    public Statement generateStatement(Long appointmentId) {
        Appointment appointment = appointmentMapper.selectById(appointmentId);
        if (!((Appointment.STATUS_ARRIVAL.equals(appointment.getStatus()) ||
                Appointment.STATUS_SETTLE.equals(appointment.getStatus())))) {
            throw new BusinessException("该预约单不能进行操作！");
        }
        // 根据预约单id获取结算单
        Statement statement = statementMapper.selectById(appointmentId);

        // 结算单对象为null，则说明预约单未生成
        if (statement == null) {
            statement = new Statement();
            LambdaUpdateWrapper<Statement> wrapper = new LambdaUpdateWrapper<>();                   // 客户姓名
            wrapper.set(Statement::getCustomerName, appointment.getCustomerName());                 // 联系方式
            wrapper.set(Statement::getCustomerPhone, appointment.getCustomerPhone());               // 到店时间
            wrapper.set(Statement::getActualArrivalTime, appointment.getActualArrivalTime());       // 车牌号码
            wrapper.set(Statement::getLicensePlate, appointment.getLicensePlate());                 // 汽车类型
            wrapper.set(Statement::getCarSeries, appointment.getCarSeries());                       // 服务类型
            wrapper.set(Statement::getServiceType, appointment.getServiceType());                   // 预约单ID
            wrapper.set(Statement::getId, appointmentId);                                           // 预约单ID
            wrapper.set(Statement::getStatus, Statement.STATUS_CONSUME);                            // 结算单状态
            wrapper.set(Statement::getInfo, appointment.getInfo());                                 // 备注信息
            statementMapper.insert(statement);
        }
        return statement;
    }
}
